package edu.cmu.cs211.exprtree.tests;



import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import edu.cmu.cs211.exprtree.ast.BinaryExpression;
import edu.cmu.cs211.exprtree.ast.Expression;
import edu.cmu.cs211.exprtree.ast.MultiplyExpression;


public class MultiplyExpressionTest extends BinaryExpressionTest {

	@Test
	public void testCfold0() {
		cfoldtest("5*3", "15");
		cfoldtest("5*x", "5*x");
		cfoldtest("x*5", "x*5");

	}

	@Test
	public void testCfold1() {
		cfoldtest("0*x", "0");
		cfoldtest("0.0*x", "0");
		cfoldtest("0.1*x", "0.1*x");
		cfoldtest("1.0*(x+1)", "x+1");
	}
	
	 
	@Test
	public void evalNoVars() {
		/* Construct the variable map */
		Map<String, BigDecimal> map = new HashMap<String, BigDecimal>();
		
		/* test the evaluate function with no variables */
		ExpressionTestUtil.evaluatetest("5*6", "30", map);
		ExpressionTestUtil.evaluatetest("(5*6)*(5*6)", "900", map);
		ExpressionTestUtil.evaluatetest("20*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1", "20", map);
	}
	
	@Test
	public void evalVars() {
		/* Construct the variable map (maybe we could do this dynamically in a loop for 
		 * a more "stressful" test?)
		 */
		Map<String, BigDecimal> map = new HashMap<String, BigDecimal>();
		map.put("x", new BigDecimal("7"));
		
		/* test the evalaute function with the current variable mapping */
		ExpressionTestUtil.evaluatetest("5*x", "35", map);
		ExpressionTestUtil.evaluatetest("x*5", "35", map);
		ExpressionTestUtil.evaluatetest("0*x", "0", map);
		ExpressionTestUtil.evaluatetest("0.0*x", "0.0", map);
		ExpressionTestUtil.evaluatetest("0.1*x", "0.7", map);
		ExpressionTestUtil.evaluatetest("x*0", "0", map);
		ExpressionTestUtil.evaluatetest("x*0.0", "0.0", map);
		ExpressionTestUtil.evaluatetest("x*0.1", "0.7", map);
		ExpressionTestUtil.evaluatetest("(0*0)*x", "0", map);
		ExpressionTestUtil.evaluatetest("x*(0*0)", "0", map);
		ExpressionTestUtil.evaluatetest("(1*1)*x", "7", map);
		ExpressionTestUtil.evaluatetest("x*(1*2)", "14", map);
		ExpressionTestUtil.evaluatetest("(x*1)*(3*2)", "42", map);
		ExpressionTestUtil.evaluatetest("(3*2)*(x*1)", "42", map);
	}
	
	@Override
	public BinaryExpression createExpr(Expression l, Expression r) {
		return new MultiplyExpression(l, r);
	}
}